package com.Flucard_IT;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import utils.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StatFs;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import controller.ConnectToServerAsync;
import define.Constants;

public class Home extends Activity implements OnGestureListener {
	/**
	 * String section
	 */
	private boolean FLAG_DELETE = false;
	private boolean FLAG_IS_LAST_ONE = false;

	private int DOWNLOAD_PROGRESS = 0;
	private int ENOUGH_SPACE = 0;
	private int SLIDE_SHOW_INDEX = 0;
	private int SLIDE_SHOW_MODE = 0;
	private int SLIDE_SHOW_TIME = 4;
	private int SWIPE_INDEX = 0;
	private final int SWIPE_MIN_DISTANCE = 120;
	private final int SWIPE_MAX_DISTANCE = 250;
	private final int SWIPE_THRESHOLD_VELOCITY = 200;
	private int DOWNLOADED_FILES = 0;

	private String DISPLAY = "";
	private String SLIDE_MODE = "", SLIDE_TIME = "";

	private final static String TAG = Home.class.getSimpleName();

	/**
	 * Data section
	 */
	private ArrayList<String> mAlDisplay = new ArrayList<String>();
	private ArrayList<String> mAlDelete = new ArrayList<String>();
	private ConcurrentLinkedQueue<String> mClqAlreadyExistingList = new ConcurrentLinkedQueue<String>();
	private ConcurrentLinkedQueue<String> mClqDownloadStatus = new ConcurrentLinkedQueue<String>();
	private ConcurrentLinkedQueue<String> mClqDownloadUrl = new ConcurrentLinkedQueue<String>();
	private ConcurrentLinkedQueue<String> mClqSaveNameString = new ConcurrentLinkedQueue<String>();

	/**
	 * Handler section
	 */
	private Handler mHandlerDownload = new Handler();
	private static Handler mHandlerFailedConnection = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			SplashScreen.mAdFailedConnection.show();
		}
	};
	private Handler mHandlerSlideShow = new Handler();

	/**
	 * Interface section
	 */
	private Runnable mRunnableDownload = new Runnable() {

		@Override
		public void run() {
			if (!mClqDownloadStatus.isEmpty()) {
				mPb.setVisibility(0);
				mClqDownloadStatus.poll();

				/**
				 * Call Download Thread to download files from Card
				 */
				new DownloadFileAsync().execute();
			}

			mHandlerDownload
					.postDelayed(this, Constants.HANDLER_DOWNLOAD_DELAY);
		}
	};
	private Runnable mRunnableSlideShow = new Runnable() {
		@Override
		public void run() {
			/**
			 * Get all files to show on the page
			 */
			getFiles();

			// Always run after delay ...
			mHandlerSlideShow.postDelayed(this, SLIDE_SHOW_TIME);
		}
	};

	/**
	 * Listener section
	 */
	private OnClickListener mListenerDelete = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int whichButton) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 4;

			SLIDE_SHOW_INDEX = 0;
			if (SWIPE_INDEX > 0 & DOWNLOADED_FILES > 0) {
				SWIPE_INDEX = SWIPE_INDEX - 1;
				DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
				mTvTitle.setText((SWIPE_INDEX + 1) + " / " + DOWNLOADED_FILES);

				Bitmap mBitmap = BitmapFactory.decodeFile(
						mAlDisplay.get(SWIPE_INDEX), options);
				mBitmap = rotate(mBitmap,
						getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
				mIvDisplay.setImageBitmap(mBitmap);
				mAlDisplay.remove(SWIPE_INDEX + 1);

				File mFile = new File(mAlDelete.get(SWIPE_INDEX + 1));
				mFile.delete();
				mAlDelete.remove(SWIPE_INDEX + 1);
			} else if (SWIPE_INDEX == 0 & DOWNLOADED_FILES > 1) {
				DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
				mTvTitle.setText("1 / " + DOWNLOADED_FILES);

				Bitmap mBitmap = BitmapFactory.decodeFile(
						mAlDisplay.get(SWIPE_INDEX + 1), options);
				mBitmap = rotate(mBitmap,
						getExifOrientation(mAlDisplay.get(SWIPE_INDEX + 1)));
				mIvDisplay.setImageBitmap(mBitmap);
				mAlDisplay.remove(SWIPE_INDEX);

				File mFile = new File(mAlDelete.get(SWIPE_INDEX));
				mFile.delete();
				mAlDelete.remove(SWIPE_INDEX);
			} else if (SWIPE_INDEX == 0 & DOWNLOADED_FILES == 1) {
				mTvTitle.setText("0 / 0");
				mIvDisplay.setImageResource(R.drawable.bg_start);

				DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
				mAlDisplay.remove(SWIPE_INDEX);

				File mFile = new File(mAlDelete.get(SWIPE_INDEX));
				mFile.delete();
				mAlDelete.remove(SWIPE_INDEX);
			}
		}
	};

	/**
	 * View section
	 */
	private AlertDialog.Builder mAdDelete;
	private AlertDialog.Builder mAdNoEnoughSpace;
	private AlertDialog.Builder mAdStartShooting;
	private AlertDialog.Builder mAdExit;
	private ImageButton mIbtnDelete;
	private ImageButton mIbtnNormal;
	private ImageButton mIbtnSlideShow;
	private ImageButton mIbtnSettings;
	private ImageView mIvDisplay;
	private ProgressBar mPb;
	private TextView mTvTitle;

	/**
	 * The others section
	 */
	private GestureDetector mGestureDetector;
	private Thread mThread;
	private SharedPreferences mSp;
	private SharedPreferences.Editor mSpEditor;

	/**
	 * On Click
	 */
	private void onClickDelete() {
		if (!FLAG_DELETE) {
			if (SWIPE_INDEX == 0 && DOWNLOADED_FILES == 0) {
			} else {
				/**
				 * Check display in which mode
				 */
				DISPLAY = mSp.getString(
						Constants.SHARED_PREFERENCE_KEY_DISPLAY, "Yes");
				if (!DISPLAY.equals("No")) {
					/**
					 * Normal Mode
					 */
					deleteInNormalMode();
				} else {
					/**
					 * Slide show Mode
					 */
					deleteInSlideShowMode();
				}
			}
		} else {
			mAdDelete.show();
		}
	}

	/**
	 * On Click from XML file
	 * 
	 * @param v
	 */
	public void onClickInstantTransfer(View v) {
		switch (v.getId()) {
		case R.id.ibtn_delete:
			onClickDelete();
			break;
		case R.id.ibtn_normal_mode:
			onClickNormalMode();
			break;
		case R.id.ibtn_setting:
			onClickSetting();
			break;
		case R.id.ibtn_slide_show_mode:
			/**
			 * If you are using PRO version, you can use the following feature :
			 * run Slide Show mode
			 */
			if (Constants.IS_VERSION_PRO) {
				onClickSlideShowMode();
			}
			break;
		default:
			break;
		}
	}

	/**
	 * Normal mode
	 */
	private void onClickNormalMode() {
		SLIDE_SHOW_MODE = 0;

		/**
		 * If you are using PRO version, you can use the following feature : run
		 * Slide Show mode
		 */
		if (Constants.IS_VERSION_PRO) {
			mIbtnSlideShow.setVisibility(View.VISIBLE);
			mIbtnNormal.setVisibility(View.GONE);
		}

		mIbtnDelete.setVisibility(0);

		if (DOWNLOADED_FILES > 0) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 4;
			Bitmap mBitmap = BitmapFactory.decodeFile(
					mAlDisplay.get(DOWNLOADED_FILES - 1), options);
			mBitmap = rotate(mBitmap,
					getExifOrientation(mAlDisplay.get(DOWNLOADED_FILES - 1)));
			mIvDisplay.setImageBitmap(mBitmap);

		}
		mTvTitle.setText(DOWNLOADED_FILES + " / " + DOWNLOADED_FILES);
	}

	/**
	 * Slide Show mode
	 */
	private void onClickSlideShowMode() {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 4;

		if (DOWNLOADED_FILES > 0 & SLIDE_SHOW_INDEX < DOWNLOADED_FILES
				& SLIDE_SHOW_INDEX >= 1) {
			Bitmap mBitmap = BitmapFactory.decodeFile(
					mAlDisplay.get(SLIDE_SHOW_INDEX - 1), options);
			mBitmap = rotate(mBitmap,
					getExifOrientation(mAlDisplay.get(SLIDE_SHOW_INDEX - 1)));
			mIvDisplay.setImageBitmap(mBitmap);
			mTvTitle.setText(SLIDE_SHOW_INDEX + " / " + DOWNLOADED_FILES);
		} else if (DOWNLOADED_FILES > 0 & SLIDE_SHOW_INDEX < DOWNLOADED_FILES) {
			Bitmap mBitmap = BitmapFactory.decodeFile(
					mAlDisplay.get(DOWNLOADED_FILES - 1), options);
			mBitmap = rotate(mBitmap,
					getExifOrientation(mAlDisplay.get(DOWNLOADED_FILES - 1)));
			mIvDisplay.setImageBitmap(mBitmap);
			mTvTitle.setText(DOWNLOADED_FILES + " / " + DOWNLOADED_FILES);
		} else if (DOWNLOADED_FILES > 0) {
			Bitmap mBitmap = BitmapFactory.decodeFile(mAlDisplay.get(0),
					options);
			mBitmap = rotate(mBitmap, getExifOrientation(mAlDisplay.get(0)));
			mIvDisplay.setImageBitmap(mBitmap);
			mTvTitle.setText(1 + " / " + DOWNLOADED_FILES);
		}

		SLIDE_SHOW_MODE = 1;
		mIbtnSlideShow.setVisibility(8);
		mIbtnNormal.setVisibility(0);
		mIbtnDelete.setVisibility(8);
	}

	private void onClickSetting() {
		Intent intent = new Intent(this, com.Flucard_IT.Settings.class);
		finish();
		startActivity(intent);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

		setContentView(R.layout.page_slide_show);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.bar);

		Constants.utils = new Utils(this);

		mGestureDetector = new GestureDetector(this);

		mSp = getSharedPreferences(Constants.SHARED_PREFERENCE_NAME,
				Context.MODE_PRIVATE);
		mSpEditor = mSp.edit();

		// Initialize methods
		initialVariables();
		initialDialog();
		initialData();

		if (!mSp.getAll().isEmpty()) {
			/**
			 * Check the saved folder name to store new images
			 */
			Constants.FOLDER_NAME = mSp.getString(
					Constants.SHARED_PREFERENCE_KEY_FOLDER,
					Constants.FOLDER_NAME);

			DISPLAY = mSp.getString(Constants.SHARED_PREFERENCE_KEY_DISPLAY,
					"Yes");

			/**
			 * If you are using PRO version, you can use the following feature :
			 * run Slide Show mode
			 */
			if (Constants.IS_VERSION_PRO) {
				SLIDE_MODE = mSp.getString(
						Constants.SHARED_PREFERENCE_KEY_SLIDESHOW_MODE, "no");
				SLIDE_TIME = mSp.getString(
						Constants.SHARED_PREFERENCE_KEY_TIME_INTERVAL, "4");

				SLIDE_SHOW_TIME = Integer.parseInt(SLIDE_TIME) * 1000;
			}
		}

		/**
		 * If you are using PRO version, you can use the following feature : run
		 * Slide Show mode
		 */
		if (Constants.IS_VERSION_PRO) {
			if (SLIDE_MODE.compareTo("yes") == 0) {
				mIbtnSlideShow.setVisibility(8);
				mIbtnNormal.setVisibility(0);
				SLIDE_SHOW_MODE = 1;
				mIbtnDelete.setVisibility(8);
			} else {
				mIbtnSlideShow.setVisibility(0);
				mIbtnNormal.setVisibility(8);
				SLIDE_SHOW_MODE = 0;
				mIbtnDelete.setVisibility(0);
			}
		}

		mSpEditor.putString(Constants.SHARED_PREFERENCE_KEY_DISPLAY, "Yes");
		mSpEditor.commit();

		/**
		 * Initialize folder name to store images
		 */
		initialFolder();

		setupData();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		/**
		 * Cancel all running Handler
		 */
		if (mHandlerDownload != null && mHandlerSlideShow != null) {
			mHandlerDownload.removeCallbacks(mRunnableDownload);
			mHandlerDownload = null;
			mHandlerSlideShow.removeCallbacks(mRunnableSlideShow);
			mHandlerSlideShow = null;
		}
	}

	@Override
	public boolean onDown(MotionEvent e) {
		return true;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 4;

		try {
			if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_DISTANCE)
				return false;
			// Right to left swipe
			if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
					&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				if (FLAG_IS_LAST_ONE) {
					SWIPE_INDEX = 0;
				} else {
					SWIPE_INDEX = SWIPE_INDEX + 1;
				}

				if (SWIPE_INDEX < mAlDisplay.size() & DOWNLOADED_FILES > 0) {
					Bitmap mBitmap = BitmapFactory.decodeFile(
							mAlDisplay.get(SWIPE_INDEX), options);
					mBitmap = rotate(mBitmap,
							getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
					mIvDisplay.setImageBitmap(mBitmap);
					mTvTitle.setText((SWIPE_INDEX + 1) + " / "
							+ DOWNLOADED_FILES);
				} else if (DOWNLOADED_FILES > 0) {
					SWIPE_INDEX = 0;
					Bitmap mBitmap = BitmapFactory.decodeFile(
							mAlDisplay.get(SWIPE_INDEX), options);
					mBitmap = rotate(mBitmap,
							getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
					mIvDisplay.setImageBitmap(mBitmap);
					mTvTitle.setText((SWIPE_INDEX + 1) + " / "
							+ DOWNLOADED_FILES);
				}
				FLAG_IS_LAST_ONE = false;
			} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
					& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				if (FLAG_IS_LAST_ONE) {
					SWIPE_INDEX = mAlDisplay.size() - 2;
				} else {
					SWIPE_INDEX = SWIPE_INDEX - 1;
				}

				if (SWIPE_INDEX >= 0 && DOWNLOADED_FILES > 0) {
					Bitmap mBitmap = BitmapFactory.decodeFile(
							mAlDisplay.get(SWIPE_INDEX), options);
					mBitmap = rotate(mBitmap,
							getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
					mIvDisplay.setImageBitmap(mBitmap);
					mTvTitle.setText((SWIPE_INDEX + 1) + " / "
							+ DOWNLOADED_FILES);
				} else if (DOWNLOADED_FILES > 0) {
					SWIPE_INDEX = mAlDisplay.size() - 1;
					Bitmap mBitmap = BitmapFactory.decodeFile(
							mAlDisplay.get(SWIPE_INDEX), options);
					mBitmap = rotate(mBitmap,
							getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
					mIvDisplay.setImageBitmap(mBitmap);
					mTvTitle.setText((SWIPE_INDEX + 1) + " / "
							+ DOWNLOADED_FILES);
				}
				FLAG_IS_LAST_ONE = false;
			} else if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE
					&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
			} else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE
					&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
			}
		} catch (Exception e) {
		}

		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK)) {
			mAdExit.show();
		}

		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onLongPress(MotionEvent e) {
	}

	@Override
	public void onResume() {
		super.onResume();

		if (Constants.utils.isNetworkOnline()) {
			/**
			 * Need check current connection still be connected the Card or not
			 */
			new ConnectToServerAsync(this).execute();

			/**
			 * Download handler
			 */
			mHandlerDownload.post(mRunnableDownload);

			/**
			 * Slide show handler
			 */
			mHandlerSlideShow.post(mRunnableSlideShow);
		} else {
			mHandlerFailedConnection.sendMessage(mHandlerFailedConnection
					.obtainMessage());
		}
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		return true;
	}

	@Override
	public void onShowPress(MotionEvent e) {
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return true;
	}

	@Override
	public boolean onTouchEvent(MotionEvent me) {
		return mGestureDetector.onTouchEvent(me);
	}

	/**
	 * Initial methods
	 */
	private void initialData() {
		/**
		 * If you are using PRO version, you can use the following feature : run
		 * Slide Show mode
		 */
		if (!Constants.IS_VERSION_PRO) {
			// Hide following Views
			mIbtnNormal.setVisibility(View.INVISIBLE);
			mIbtnSlideShow.setVisibility(View.GONE);
			mIbtnSettings.setVisibility(View.INVISIBLE);
		}

		mIvDisplay.setImageResource(R.drawable.bg_start);
		mPb.setVisibility(8);
		mTvTitle.setText(SWIPE_INDEX + " / " + DOWNLOADED_FILES);
	}

	private void initialDialog() {
		mAdDelete = new AlertDialog.Builder(this)
				.setTitle("")
				.setMessage(R.string.dialog_delete_error)
				.setPositiveButton(getString(R.string.ok),
						new OnClickListener() {
							@Override
							public void onClick(DialogInterface d,
									int whichButton) {
							}
						});

		mAdExit = new AlertDialog.Builder(this)
				.setTitle(R.string.title_exit)
				.setIcon(R.drawable.ic_info)
				.setCancelable(false)
				.setMessage(R.string.content_exit)
				.setPositiveButton(R.string.ok, new OnClickListener() {
					@Override
					public void onClick(DialogInterface d, int whichButton) {
						android.os.Process.killProcess(android.os.Process
								.myPid());
					}
				})
				.setNegativeButton(R.string.cancel,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog9,
									int whichButton) {
							}
						});

		mAdNoEnoughSpace = new AlertDialog.Builder(this)
				.setTitle("")
				.setMessage(R.string.no_enough_space)
				.setPositiveButton(getString(R.string.ok),
						new OnClickListener() {
							@Override
							public void onClick(DialogInterface d,
									int whichButton) {
								android.os.Process
										.killProcess(android.os.Process.myPid());
							}
						});

		mAdStartShooting = new AlertDialog.Builder(this)
				.setTitle("")
				.setMessage(R.string.start_taking_photos)
				.setPositiveButton(getString(R.string.ok),
						new OnClickListener() {
							@Override
							public void onClick(DialogInterface d,
									int whichButton) {
							}
						});
	}

	private void initialFolder() {
		File mFileParent = new File(Constants.FOLDER_ROOT);
		if (!mFileParent.exists() || !mFileParent.isDirectory()) {
			mFileParent.mkdir();
		}

		File mFileChild = new File(Constants.FOLDER_ROOT
				+ Constants.FOLDER_NAME + "/");
		if (!mFileChild.exists() || !mFileChild.isDirectory()) {
			mFileChild.mkdir();
		}
	}

	private void initialVariables() {
		mIbtnDelete = (ImageButton) findViewById(R.id.ibtn_delete);
		mIvDisplay = (ImageView) findViewById(R.id.iv_display_photo);
		mIbtnNormal = (ImageButton) findViewById(R.id.ibtn_normal_mode);
		mIbtnSettings = (ImageButton) findViewById(R.id.ibtn_setting);
		mIbtnSlideShow = (ImageButton) findViewById(R.id.ibtn_slide_show_mode);
		mPb = (ProgressBar) findViewById(R.id.progress_bar);
		mTvTitle = (TextView) findViewById(R.id.title_bar_text);
	}

	/**
	 * Basic methods
	 */

	private double availableSpace() {
		StatFs s = new StatFs(Environment.getExternalStorageDirectory()
				.getPath());
		return (double) s.getAvailableBlocks() * (double) s.getBlockSize();
	}

	private void deleteInNormalMode() {
		LayoutInflater mLi = LayoutInflater.from(this);
		final View v = mLi.inflate(R.layout.confirm, null);

		CheckBox mCb = (CheckBox) v.findViewById(R.id.cb_);
		TextView mTvHide = (TextView) v.findViewById(R.id.tv_hide);

		mCb.setChecked(false);
		mTvHide.setText(R.string.content_hide);

		mCb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if (isChecked) {
					mSpEditor.putString(
							Constants.SHARED_PREFERENCE_KEY_DISPLAY, "No");
					mSpEditor.commit();
				}
			}
		});

		AlertDialog.Builder mAd = new AlertDialog.Builder(this)
				.setTitle(R.string.note)
				.setMessage(R.string.content_delete)
				.setView(v)
				.setPositiveButton(getString(R.string.ok), mListenerDelete)
				.setNegativeButton(getString(R.string.cancel),
						new OnClickListener() {
							@Override
							public void onClick(DialogInterface d,
									int whichButton) {
							}
						});
		mAd.show();
	}

	private void deleteInSlideShowMode() {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 4;

		if (SWIPE_INDEX > 0 && DOWNLOADED_FILES > 0) {
			SWIPE_INDEX = SWIPE_INDEX - 1;
			DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
			mTvTitle.setText((SWIPE_INDEX + 1) + " / " + DOWNLOADED_FILES);
			Bitmap mBitmap = BitmapFactory.decodeFile(
					mAlDisplay.get(SWIPE_INDEX), options);
			mBitmap = rotate(mBitmap,
					getExifOrientation(mAlDisplay.get(SWIPE_INDEX)));
			mIvDisplay.setImageBitmap(mBitmap);
			mAlDisplay.remove(SWIPE_INDEX + 1);

			File mFile = new File(mAlDelete.get(SWIPE_INDEX + 1));
			mFile.delete();

			mAlDelete.remove(SWIPE_INDEX + 1);
		} else if (SWIPE_INDEX == 0 && DOWNLOADED_FILES > 1) {
			DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
			mTvTitle.setText("1 / " + DOWNLOADED_FILES);
			Bitmap mBitmap = BitmapFactory.decodeFile(
					mAlDisplay.get(SWIPE_INDEX + 1), options);
			mBitmap = rotate(mBitmap,
					getExifOrientation(mAlDisplay.get(SWIPE_INDEX + 1)));
			mIvDisplay.setImageBitmap(mBitmap);
			mAlDisplay.remove(SWIPE_INDEX);

			File mFile = new File(mAlDelete.get(SWIPE_INDEX));
			mFile.delete();

			mAlDelete.remove(SWIPE_INDEX);
		} else if (SWIPE_INDEX == 0 && DOWNLOADED_FILES == 1) {
			mTvTitle.setText("0 / 0");
			mIvDisplay.setImageResource(R.drawable.bg_start);

			DOWNLOADED_FILES = DOWNLOADED_FILES - 1;
			mAlDisplay.remove(SWIPE_INDEX);

			File mFile = new File(mAlDelete.get(SWIPE_INDEX));
			mFile.delete();

			mAlDelete.remove(SWIPE_INDEX);
		}
	}

	private synchronized static int getExifOrientation(String filepath) {
		int degree = 0;
		ExifInterface exif = null;
		try {
			exif = new ExifInterface(filepath);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (exif != null) {
			int orientation = exif.getAttributeInt(
					ExifInterface.TAG_ORIENTATION, -1);

			if (orientation != -1) {
				switch (orientation) {
				case ExifInterface.ORIENTATION_ROTATE_90:
					degree = 90;
					break;
				case ExifInterface.ORIENTATION_ROTATE_180:
					degree = 180;
					break;
				case ExifInterface.ORIENTATION_ROTATE_270:
					degree = 270;
					break;
				}
			}
		}
		return degree;

	}

	private void getFiles() {
		/**
		 * If slide show mode is 1, show pictures
		 */
		if (SLIDE_SHOW_MODE == 1) {
			FLAG_DELETE = true;

			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 4;
			if (DOWNLOADED_FILES > 0 && SLIDE_SHOW_INDEX < DOWNLOADED_FILES) {
				Bitmap mBitmap = BitmapFactory.decodeFile(
						mAlDisplay.get(SLIDE_SHOW_INDEX), options);
				mBitmap = rotate(mBitmap,
						getExifOrientation(mAlDisplay.get(SLIDE_SHOW_INDEX)));
				mIvDisplay.setImageBitmap(mBitmap);
				mTvTitle.setText(SLIDE_SHOW_INDEX + 1 + " / "
						+ DOWNLOADED_FILES);
				SLIDE_SHOW_INDEX++;
			} else if (DOWNLOADED_FILES > 0) {
				SLIDE_SHOW_INDEX = 0;
				Bitmap mBitmap = BitmapFactory.decodeFile(
						mAlDisplay.get(SLIDE_SHOW_INDEX), options);
				mBitmap = rotate(mBitmap,
						getExifOrientation(mAlDisplay.get(SLIDE_SHOW_INDEX)));
				mIvDisplay.setImageBitmap(mBitmap);
				mTvTitle.setText(SLIDE_SHOW_INDEX + 1 + " / "
						+ DOWNLOADED_FILES);
				SLIDE_SHOW_INDEX++;
			}
		} else {
			FLAG_DELETE = false;
		}
	}

	// add new download URL items into existing list
	// which contains all download URLs
	// add only new items to forSaveName and for Download
	private void getFileName() {
		try {
			HttpClient mHttpClient = new DefaultHttpClient();
			HttpGet mHttpGet = new HttpGet("http://" + Constants.IP
					+ "/cgi-bin/photo");
			HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
			InputStream mIs = mHttpResponse.getEntity().getContent();
			BufferedReader mBr = new BufferedReader(new InputStreamReader(mIs));

			String LINE = null;
			while ((LINE = mBr.readLine()) != null) {
				if (LINE.indexOf("download?fn=") != -1
						&& LINE.indexOf("target=_blank") != -1) {
					if (!mClqAlreadyExistingList.contains(LINE.substring(
							LINE.indexOf("download?fn=") + 12,
							LINE.indexOf("target=_blank") - 1))) {
						mClqAlreadyExistingList.add(LINE.substring(
								LINE.indexOf("download?fn=") + 12,
								LINE.indexOf("target=_blank") - 1));
						mClqDownloadUrl.add(LINE.substring(
								LINE.indexOf("download?fn=") + 12,
								LINE.indexOf("target=_blank") - 1));
						mClqSaveNameString.add(LINE.substring(
								LINE.indexOf("download?fn=") + 12,
								LINE.indexOf("&fd=")));
					}
				}
			}

			mIs.close();
		} catch (MalformedURLException e) {
		} catch (IOException e) {
		}
	}

	/**
	 * 
	 * @param bitmap
	 * @param degrees
	 * @return
	 */
	private Bitmap rotate(Bitmap bitmap, int degrees) {
		if (degrees != 0 && bitmap != null) {
			Matrix m = new Matrix();
			m.setRotate(degrees, (float) bitmap.getWidth() / 2,
					(float) bitmap.getHeight() / 2);
			try {
				Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0,
						bitmap.getWidth(), bitmap.getHeight(), m, true);
				if (bitmap != converted) {
					bitmap.recycle();
					bitmap = converted;
				}
			} catch (OutOfMemoryError ex) {

			}
		}
		return bitmap;
	}

	private void setupData() {
		// Add data
		mClqDownloadStatus.add("ready");

		/**
		 * Only show the message once
		 */
		if (SplashScreen.IS_FIRST_TIME) {
			SplashScreen.IS_FIRST_TIME = false;
			// Show alert dialog
			mAdStartShooting.show();
		}

		// start thread
		mThread = new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				getFileName();
			}
		};
		mThread.start();
	}

	/**
	 * Classes
	 */

	private class DownloadFileAsync extends AsyncTask<Void, String, Void> {
		/**
		 * Load images from SD Card in the background, and display each image on
		 * the screen.
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected Void doInBackground(Void... params) {
			// Get file name
			getFileName();

			int restart = 0;
			int downtotal = 0;

			while (!mClqDownloadUrl.isEmpty() | restart != 0) {
				try {
					downloadStatus(restart, downtotal);
				} catch (Throwable t) {
				}
			}

			mClqDownloadStatus.add("ready");

			return null;
		}

		@Override
		protected void onPreExecute() {
			mPb.setVisibility(0);
		}

		/**
		 * Add a new LoadedImage in the images grid.
		 * 
		 * @param value
		 */
		@Override
		public void onProgressUpdate(String... value) {
			DOWNLOADED_FILES++;
			if (ENOUGH_SPACE == 1) {
				ENOUGH_SPACE = 0;
				mAdNoEnoughSpace.show();
			} else if (SLIDE_SHOW_MODE == 1) {
				mAlDisplay.add(value[0]);
				mAlDelete.add(value[0]);
				FLAG_IS_LAST_ONE = true;
			} else {
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize = 4;

				Bitmap mBitmap = BitmapFactory.decodeFile(value[0], options);
				mBitmap = rotate(mBitmap, getExifOrientation(value[0]));

				mAlDisplay.add(value[0]);
				mAlDelete.add(value[0]);

				mIvDisplay.setImageBitmap(mBitmap);
				mTvTitle.setText(DOWNLOADED_FILES + " / " + DOWNLOADED_FILES);

				FLAG_IS_LAST_ONE = true;
			}
		}

		/**
		 * Set the visibility of the progress bar to false.
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(Void result) {
			mPb.setVisibility(8);
		}

		/**
		 * @param FILE_PATH
		 * @param FILE_NAME
		 * @param DOWNLOAD
		 * @param RESTART
		 * @param DOWN_TOTAL
		 * @throws IOException
		 */
		private void downloadFilesToExistedFolder(String FILE_PATH,
				String FILE_NAME, String DOWNLOAD, int RESTART, int DOWN_TOTAL)
				throws IOException {
			int file_length;

			HttpURLConnection mHttpURLConnection;
			InputStream mIs;
			OutputStream mOs;
			URL URL;

			URL = new URL("http://" + Constants.IP + "/cgi-bin/download?fn="
					+ DOWNLOAD);
			mHttpURLConnection = (HttpURLConnection) URL.openConnection();
			mHttpURLConnection.setReadTimeout(5000);
			mHttpURLConnection.connect();

			file_length = mHttpURLConnection.getContentLength();

			if (file_length / 1024 / 1024 > availableSpace() / 1024 / 1024) {
				ENOUGH_SPACE = 1;
				publishProgress();
			} else {
				mIs = mHttpURLConnection.getInputStream();
				mOs = new FileOutputStream(Constants.FOLDER_ROOT
						+ Constants.FOLDER_NAME + "/" + FILE_NAME);

				byte data[] = new byte[512];
				while ((DOWNLOAD_PROGRESS = mIs.read(data)) != -1) {
					mOs.write(data, 0, DOWNLOAD_PROGRESS);
					DOWN_TOTAL = DOWN_TOTAL + DOWNLOAD_PROGRESS;
				}

				if (DOWN_TOTAL < file_length) {
					RESTART = 1;

					File file = new File(Constants.FOLDER_ROOT
							+ Constants.FOLDER_NAME + "/" + FILE_NAME);
					file.delete();
				} else {
					RESTART = 0;
					publishProgress(FILE_PATH);
				}

				// Reset all things
				DOWNLOAD_PROGRESS = 0;
				file_length = 0;
				mOs.flush();
				mOs.close();
				mIs.close();
			}

			// Disconnect URL connection
			mHttpURLConnection.disconnect();
		}

		/**
		 * @throws IOException
		 */
		private void downloadStatus(int RESTART, int DOWN_TOTAL)
				throws IOException {
			String FILE_NAME = "";
			String FILE_PATH = "";
			String DOWNLOAD = "";

			if (RESTART == 0) {
				FILE_NAME = mClqSaveNameString.poll();
				DOWNLOAD = mClqDownloadUrl.poll();
			}

			/**
			 * Check the saved folder name to store new images
			 */
			if (mSp.getString(Constants.SHARED_PREFERENCE_KEY_FOLDER,
					Constants.FOLDER_NAME) != null) {
				Constants.FOLDER_NAME = mSp.getString(
						Constants.SHARED_PREFERENCE_KEY_FOLDER,
						Constants.FOLDER_NAME);
			}

			FILE_PATH = Constants.FOLDER_ROOT + Constants.FOLDER_NAME + "/"
					+ FILE_NAME;
			File mFile = new File(FILE_PATH);
			if (mFile.exists()) {
				/**
				 * If file already existed, load it
				 */
				publishProgress(FILE_PATH);
			} else {
				/**
				 * If file has not existed yet, begin download it to the folder
				 * name
				 */
				downloadFilesToExistedFolder(FILE_PATH, FILE_NAME,
						DOWNLOAD, RESTART, DOWN_TOTAL);
			}
		}
	}
}
